import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import mplfinance as mpf
import matplotlib.dates as mdates
import datetime as dt
import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio
from plotly.subplots import make_subplots
pio.renderers.default = "notebook"
pio.templates.default = "plotly_dark"
import gc
np.random.seed(42)
import warnings
warnings.filterwarnings("ignore")
plt.rcParams["figure.figsize"] = [12, 8]
The idea is that investors, in order to be encouraged to invest in businesses, should have protection against liability for what the managers of the business do. So, an investor should not be liable for the debts or mistake of the business. This is the idea of limited liability.
The idea wah enuciated first in 1811 by New York State.
Instead of using a currency which is liable of changes, inflation indexed debt uses some index to tie the debt to that index.
A way to deal with inflation.
Something that happended on past is not the represenative of what will happen in future.
Random walk theory suggests that changes in stock prices have the same distribution and are independent of each other. Therefore, it assumes the past movement or trend of a stock price or market cannot be used to predict its future movement. In short, random walk theory proclaims that stocks take a random and unpredictable path that makes all methods of predicting stock prices futile in the long run.
We have
$$ x_{t} = x_{t-1}+\epsilon_t $$where $\epsilon$ is a noise and is completely unforcastable.
apple = pd.read_csv("Data/AAPL.csv", parse_dates=["Date"], index_col="Date")
google = pd.read_csv("Data/GOOG.csv", parse_dates=["Date"], index_col="Date")
apple.head()
| Open | High | Low | Close | Volume | |
|---|---|---|---|---|---|
| Date | |||||
| 1980-12-12 00:00:00-05:00 | 0.099874 | 0.100308 | 0.099874 | 0.099874 | 469033600 |
| 1980-12-15 00:00:00-05:00 | 0.095098 | 0.095098 | 0.094663 | 0.094663 | 175884800 |
| 1980-12-16 00:00:00-05:00 | 0.088149 | 0.088149 | 0.087715 | 0.087715 | 105728000 |
| 1980-12-17 00:00:00-05:00 | 0.089886 | 0.090320 | 0.089886 | 0.089886 | 86441600 |
| 1980-12-18 00:00:00-05:00 | 0.092492 | 0.092927 | 0.092492 | 0.092492 | 73449600 |
apple = apple[apple.index >= pd.to_datetime("2022-01-01", format="%Y-%m-%d", utc=True)]
apple = apple[["Close"]]
apple.head()
| Close | |
|---|---|
| Date | |
| 2022-01-03 00:00:00-05:00 | 180.959732 |
| 2022-01-04 00:00:00-05:00 | 178.663071 |
| 2022-01-05 00:00:00-05:00 | 173.910660 |
| 2022-01-06 00:00:00-05:00 | 171.007507 |
| 2022-01-07 00:00:00-05:00 | 171.176544 |
px.line(apple, x=apple.index, y="Close", title="Apple Stock Price")
sigma = apple["Close"].std()
print("Standard Deviation: ", sigma)
Standard Deviation: 12.466134262158613
sigma = 3
walk_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
walk_prices.append(cur_price)
for i in range(1, 200):
cur_price = cur_price + np.random.normal(0, sigma)
walk_prices.append(cur_price)
walk_prices = np.array(walk_prices)
fig = px.line(x=range(0, 200), y=walk_prices, title="Apple Stock Price (Random Walk)")
fig.update_xaxes(title_text="Days")
fig.update_yaxes(title_text="Price")
fig.show()
Let's merge both the plots on one graph.
# walk_prices = np.array(walk_prices)
# prices = np.concatenate((apple["Close"].values, new_prices))
# prices = pd.DataFrame(prices, columns=["Close"])
# prices.index = apple.index.append(pd.date_range(start=apple.index[-1], periods=200, freq="D"))
# prices.head()
fig = px.line(
y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
y=walk_prices,
x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(walk_prices)),
mode="lines",
name="Random Walk",
)
Next, we'll repeat the simulation a number of times and plot the results.
def simulate_one(days=200, sigma=3):
walk_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
walk_prices.append(cur_price)
for i in range(1, 200):
cur_price = cur_price + np.random.normal(0, sigma)
walk_prices.append(cur_price)
walk_prices = np.array(walk_prices)
return walk_prices
# simulate 100 random walks and plot them
# We'll also plot the mean of the random walks
walk_prices = simulate_one()
sum_walk_price = walk_prices
fig = px.line(y=walk_prices, x=np.arange(0, 200))
for i in range(100):
walk_prices = simulate_one()
sum_walk_price += walk_prices
fig.add_scatter(y=walk_prices, x=np.arange(0, 200), mode="lines", name=f"S_{i+1}")
fig.add_scatter(
y=sum_walk_price / 100,
x=np.arange(0, 200),
mode="lines",
name=f"Avereged",
line=dict(color="royalblue", width=4),
)
fig.show()
In this case, we have
$$ x_t = x_0 + \rho(x_{t-1}-x_0) + \epsilon _t $$$x_0$ is the initial position. If $\rho =1$ this gives the random walk.
This is a modified version of random walk. The middle term means that as the position is away from the mean position, it will try to move to the mean position.
rho = 0.1
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
cur_price = (
start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
)
ar_prices.append(cur_price)
fig = px.line(
y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
y=ar_prices,
x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
mode="lines",
name=f"AR(1) for rho={rho}",
)
rho = 0.5
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
cur_price = (
start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
)
ar_prices.append(cur_price)
fig = px.line(
y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
y=ar_prices,
x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
mode="lines",
name=f"AR(1) for rho={rho}",
)
rho = 0.9
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
cur_price = (
start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
)
ar_prices.append(cur_price)
fig = px.line(
y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
y=ar_prices,
x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
mode="lines",
name=f"AR(1) for rho={rho}",
)
rho = 1.0
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
cur_price = (
start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
)
ar_prices.append(cur_price)
fig = px.line(
y=apple["Close"], x=np.arange(0, len(apple["Close"])), title="Apple Stock Price"
)
fig.add_scatter(
y=ar_prices,
x=np.arange(len(apple["Close"]), len(apple["Close"]) + len(ar_prices)),
mode="lines",
name=f"AR(1) for rho={rho}",
)
Same as before, we'll make a plot with multiple simulations. We'll be using $\rho = 0.9$
def simulate_one(days=200, sigma=3, rho=0.9):
ar_prices = []
start_price = apple["Close"].iloc[-1]
cur_price = start_price
ar_prices.append(cur_price)
for i in range(1, 200):
cur_price = (
start_price + rho * (cur_price - start_price) + np.random.normal(0, sigma)
)
ar_prices.append(cur_price)
ar_prices = np.array(ar_prices)
return ar_prices
ar_prices = simulate_one()
sum_ar_price = ar_prices
fig = px.line(y=ar_prices, x=np.arange(0, 200))
for i in range(100):
ar_prices = simulate_one()
sum_ar_price += ar_prices
fig.add_scatter(y=ar_prices, x=np.arange(0, 200), mode="lines", name=f"S_{i+1}")
fig.add_scatter(
y=sum_ar_price / 100,
x=np.arange(0, 200),
mode="lines",
name=f"Avereged",
line=dict(color="royalblue", width=4),
)
fig.show()
Weak Form: prices incorporate information about past prices
Semi Strong Form: all publicly information is already incorporated in the market prices
Strong Form: all information including inside information held by the companies is already incorporated in the stock prices, prices because it leaks out.
The hypothesis is only a "half truth".
Discounted present value is a concept in economics and finance that refers to a method of measuring the value of payments or utility that will be received in the future. Most people would agree that receiving $1,000 today is better than receiving $1,000 in a year, because $1,000 today can be used for consumption or investment.
By Gordon model, if the earnings by a stock is due to dividends and the dividends grow with factor g, we have:
$$ P = \frac{E}{r-g}\\ \frac{P}{E} = \frac{1}{r-g} $$$E$ can be seen as the value of the next year's dividends.
This means that if the P/E ratio is higher it would either have to be because it's low risk as measured by beta, so we willing to pay more for it because it's low risk. Or would have to be that people have reason to think that they're earning path the gross rate g is high.
People are rational and are trying to maximize their utility which is an measure of happiness.
Example: Let's say I toss a coin. If it turns head, I'll give you 200 and if it turns tail you'll give me 100. So, you have an expected return of 50. By expected utility theory, you should take the bet. However, people don't usually take the bet.
This can be understood by the prospect thoery. People don't take the bet because the gaining 200 gives a little happiness but losing 100 gives a lot of unhappiness. This is called the loss aversion namely, people are more afraid of loosing. ("You are always worried about little losses today.")

Prospect theory is is a experimentally based set of knowledge about mistakes that people make. This is based on research by Kahneman and Tversky of people making decisions under uncertainty and is a modification of the expected utility theory. The theory is based on some real life facts such as:
The main assumption of the prospect theory is that people are not very ration which is in contrast with the traditional economic models that people are very sensible and calculating.
Efficient market hypothesis and behavioral finance are two main revolution of past 50-60 years. These two revolutions are kind of incompatible views of the world. But they both offer insights, they're both exciting.
Anchoring refers to a tendency in ambiguous situations to allow one's decisions to be affected by some anchor. it's the same way I think with stock prices, that stock prices are anchored to past values. Nobody knows what this company is worth but it was worth something yesterday.